package controller

import (
	"dsc-server/domain/dto"
	"dsc-server/pkg/model"
	"dsc-server/pkg/service"
	"encoding/base64"
	"github.com/liangboceo/yuanboot/web/context"
	"io"
	"log"
	"net/http"
	"strconv"
	"strings"

	"gorm.io/gorm"
)

// ApiConfigController API配置控制器
type ApiConfigController struct {
	BaseController
	DB                *gorm.DB
	ApiConfigService  *service.ApiConfigService
	DataSourceService *service.DataSourceService
	GroupService      *service.GroupService
	Host              string // 配置中的主机地址
}

// NewApiConfigController 创建ApiConfigController实例
func NewApiConfigController(db *gorm.DB) *ApiConfigController {
	return &ApiConfigController{
		DB:                db,
		ApiConfigService:  service.NewApiConfigService(db),
		DataSourceService: service.NewDataSourceService(db),
		GroupService:      service.NewGroupService(db),
		Host:              "devwxapp.rhecube.com/api/datamarket", // 默认值，可通过配置文件覆盖
	}
}

// Add 添加API配置
func (ctrl *ApiConfigController) Add(ctx *context.HttpContext) {
	var apiConfig model.ApiConfig
	if err := c.ShouldBind(&apiConfig); err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "参数绑定失败"))
		return
	}

	// 处理Base64编码的SQL
	if isBase64(apiConfig.Sql) {
		decoded, err := base64.StdEncoding.DecodeString(apiConfig.Sql)
		if err == nil {
			apiConfig.Sql = string(decoded)
		}
	}

	result := ctrl.ApiConfigService.Add(&apiConfig)
	c.JSON(http.StatusOK, result)
}

// ParseParam 解析SQL参数
func (ctrl *ApiConfigController) ParseParam(ctx *context.HttpContext) {
	sql := c.Query("sql")

	// 处理Base64编码的SQL
	if isBase64(sql) {
		decoded, err := base64.StdEncoding.DecodeString(sql)
		if err == nil {
			sql = string(decoded)
		}
	}

	// TODO: 实现SQL参数解析
	// 这里需要实现类似于Java中SqlEngineUtil.getEngine().parseParameter(sql)的功能
	// 由于Go没有直接对应的库，这里只是一个示例
	parameters := parseParameters(sql)

	// 转换为前端需要的格式
	var result []map[string]string
	for _, param := range parameters {
		result = append(result, map[string]string{
			"value": param,
		})
	}

	c.JSON(http.StatusOK, dto.Success(result))
}

// GetAll 获取所有API配置
func (ctrl *ApiConfigController) GetAll(ctx *context.HttpContext) {
	keyword := c.Query("keyword")
	field := c.Query("field")
	groupId := c.Query("groupId")

	// 设置分页参数
	pageNum, pageSize, orderBy := ctrl.StartPage(c)

	// 查询数据
	apiConfigs, err := ctrl.ApiConfigService.Search(keyword, field, groupId)
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "查询失败"))
		return
	}

	// TODO: 实现分页
	// 这里简化处理，实际应用中需要实现真正的分页逻辑
	total := int64(len(apiConfigs))
	hasNextPage := int64(pageNum*pageSize) < total

	// 响应数据
	ctrl.GetDataTable(c, apiConfigs, total, hasNextPage)
}

// GetApiTree 获取API树
func (ctrl *ApiConfigController) GetApiTree() {
	result, err := ctrl.ApiConfigService.GetAllDetail()
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "获取API树失败"))
		return
	}

	c.JSON(http.StatusOK, result)
}

// Detail 获取API配置详情
func (ctrl *ApiConfigController) Detail(ctx *context.HttpContext) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "ID参数错误"))
		return
	}

	apiConfig, err := ctrl.ApiConfigService.Detail(uint(id))
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "获取详情失败"))
		return
	}

	c.JSON(http.StatusOK, apiConfig)
}

// Delete 删除API配置
func (ctrl *ApiConfigController) Delete(ctx *context.HttpContext) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "ID参数错误"))
		return
	}

	path, err := ctrl.ApiConfigService.GetPath(uint(id))
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "获取路径失败"))
		return
	}

	result := ctrl.ApiConfigService.Delete(uint(id), path)
	c.JSON(http.StatusOK, result)
}

// Update 更新API配置
func (ctrl *ApiConfigController) Update(ctx *context.HttpContext) {
	var apiConfig model.ApiConfig
	if err := c.ShouldBind(&apiConfig); err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "参数绑定失败"))
		return
	}

	// 处理Base64编码的SQL
	if isBase64(apiConfig.Sql) {
		decoded, err := base64.StdEncoding.DecodeString(apiConfig.Sql)
		if err == nil {
			apiConfig.Sql = string(decoded)
		}
	}

	result := ctrl.ApiConfigService.Update(&apiConfig)
	c.JSON(http.StatusOK, result)
}

// Online 上线API配置
func (ctrl *ApiConfigController) Online(ctx *context.HttpContext) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "ID参数错误"))
		return
	}

	path, err := ctrl.ApiConfigService.GetPath(uint(id))
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "获取路径失败"))
		return
	}

	result := ctrl.ApiConfigService.Online(uint(id), path)
	c.JSON(http.StatusOK, result)
}

// Offline 下线API配置
func (ctrl *ApiConfigController) Offline(ctx *context.HttpContext) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "ID参数错误"))
		return
	}

	path, err := ctrl.ApiConfigService.GetPath(uint(id))
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "获取路径失败"))
		return
	}

	result := ctrl.ApiConfigService.Offline(uint(id), path)
	c.JSON(http.StatusOK, dto.Success(true))
}

// GetIPPort 获取IP和端口
func (ctrl *ApiConfigController) GetIPPort(ctx *context.HttpContext) {
	c.JSON(http.StatusOK, dto.Success(ctrl.Host))
}

// ApiDocs 生成API文档
func (ctrl *ApiConfigController) ApiDocs(ctx *context.HttpContext) {
	idsStr := c.Query("ids")
	if idsStr == "" {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "参数错误"))
		return
	}

	// 解析ID列表
	var ids []uint
	for _, idStr := range strings.Split(idsStr, ",") {
		id, err := strconv.ParseUint(idStr, 10, 32)
		if err != nil {
			continue
		}
		ids = append(ids, uint(id))
	}

	// 生成文档
	docs, err := ctrl.ApiConfigService.ApiDocs(ids)
	if err != nil {
		c.JSON(http.StatusOK, dto.FailureMessage(nil, "生成文档失败"))
		return
	}

	// 设置响应头
	c.Header("Content-Type", "application/x-msdownload;charset=utf-8")
	c.Header("Content-Disposition", "attachment; filename=接口文档.md")

	// 写入响应体
	_, err = io.WriteString(c.Writer, docs)
	if err != nil {
		log.Printf("写入响应失败: %v", err)
	}
}

// 辅助函数

// isBase64 判断字符串是否为Base64编码
func isBase64(s string) bool {
	_, err := base64.StdEncoding.DecodeString(s)
	return err == nil && len(s) > 0 && len(s)%4 == 0
}

// parseParameters 解析SQL中的参数
// 这是一个简化版的实现，实际应用中需要更复杂的SQL解析
func parseParameters(sql string) []string {
	// 简单实现：查找 #{param} 格式的参数
	var params []string
	start := 0
	for {
		start = strings.Index(sql[start:], "#{")
		if start == -1 {
			break
		}
		end := strings.Index(sql[start:], "}")
		if end == -1 {
			break
		}
		param := sql[start+2 : start+end]
		params = append(params, param)
		start = start + end + 1
	}
	return params
}
